package com.hd.trans.ui.fragment

import android.animation.ObjectAnimator
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.biubiu.universaladapter.RecyclerViewAdapter
import com.hd.trans.R
import com.hd.trans.TranslationInterior
import com.hd.trans.common.Constants.VOICE_RECOGNIZING
import com.hd.trans.common.Constants.VOICE_RECORD_PAUSE
import com.hd.trans.databinding.FragmentSimulMergeBinding
import com.hd.trans.extension.observe
import com.hd.trans.extension.scrollToBottom
import com.hd.trans.network.bean.TransSubsection
import com.hd.trans.ui.activity.customize.SimulTranslateActivity
import com.hd.trans.ui.adapter.vm.MergeSubsectionVm
import com.hd.trans.ui.adapter.vm.SpaceVm
import com.hd.trans.ui.base.DataBindingBaseFragment
import com.hd.trans.utils.AnimationUtil
import com.hd.trans.utils.ClipboardUtils
import com.hd.trans.utils.LogUtil
import com.hd.trans.utils.ScreenUtil
import com.hd.trans.utils.ToastUtils
import com.hd.trans.utils.preference.Preferences
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.concurrent.atomic.AtomicReference

/**
 * 同声传译合屏时页面
 */
class SimulMergeFragment: DataBindingBaseFragment<FragmentSimulMergeBinding>() {
    private var isInitViews: Boolean = false
    private var sysBtnRippleAmin: ObjectAnimator? = null
    private var mUpdateSubsectionRunnable:Runnable? = null

    private val mParent by lazy {
        activity as SimulTranslateActivity
    }

    private val mViewModel by lazy {
        mParent.mViewModel
    }

    private val topSpaceVm by lazy {
        SpaceVm(ScreenUtil.dp2px(0f))
    }

    private val mSubsectionVm by lazy {
        MergeSubsectionVm().apply {
            onContentDisplay = {
                hideLoadingViews(it)
            }
        }
    }

    override fun getLayoutId(): Int {
        return R.layout.fragment_simul_merge
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        observe()
        super.onCreate(savedInstanceState)
    }

    override fun onDestroy() {
        super.onDestroy()
        sysBtnRippleAmin?.cancel()
    }

    override fun initViewsAndEvents(savedInstanceState: Bundle?) {
        initView()
        initAdapter()
        initData()
    }

    private fun observe() {
        observe(mViewModel.languageFrom) {
        }

        observe(mViewModel.languageTo) {
        }
        observe(mViewModel.voiceState) {
            onRecordingStateChange(it)
        }
    }

    private fun initView() {
        isInitViews = true
        mDataBinding.apply {
            click = this@SimulMergeFragment
            ivSysSound.alpha = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) 1f else 0.6f

            updateVoicePlayButton()
            onStateChange()
        }
    }

    private fun initAdapter() {
        mDataBinding.apply {
            rvWhole.layoutManager = LinearLayoutManager(mParent)
            rvWhole.adapter = RecyclerViewAdapter(topSpaceVm,mSubsectionVm,SpaceVm(ScreenUtil.dp2px(60f)))

            //监听rvWhole是否滑到顶部
            rvWhole.addOnScrollListener(object : RecyclerView.OnScrollListener(){
                override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                    super.onScrollStateChanged(recyclerView, newState)
                    if (newState == RecyclerView.SCROLL_STATE_IDLE){
                        updateListMaskVisible()
                    }
                }
            })
        }
    }

    private fun initData() {
    }

    private fun hideLoadingViews(hasContent:Boolean){
        mDataBinding.rlLoadingAnim.isVisible = !hasContent && mViewModel.isRecording()
        mDataBinding.ivCopyIcon.alpha = if (hasContent) 1f else 0.6f
    }

    private fun showHideHeadsetTips(show:Boolean){
        mDataBinding.vSysRipple.isVisible = show
        mDataBinding.rlHeadsetTips.isVisible = show

        if (show) {
            if (sysBtnRippleAmin == null) {
                sysBtnRippleAmin =
                    AnimationUtil.heartBeat(mDataBinding.vSysRipple, 0.1f, 2000L)
            }
            sysBtnRippleAmin?.start()
        }else{
            sysBtnRippleAmin?.cancel()
        }
    }

    /**
     * 更新语音状态
     */
    private fun onRecordingStateChange(state: Int) {
        val isStop = mViewModel.isStop()

        mDataBinding.llRecordingButtons.isVisible = !isStop
        mDataBinding.btnStart.isVisible = isStop

        if (isStop){
            updateVoicePlayButton(false)
        }
        else{
            updateVoicePlayButton()
        }
        when(state){
            VOICE_RECOGNIZING -> {
                mDataBinding.rlLoadingAnim.isVisible = !mParent.getSubsectionSet().isContentNotEmpty()
                mDataBinding.rlDefaultBg.isVisible = false
                mDataBinding.ivPause.setImageResource(R.mipmap.trans_ic_simu_pause)
                mDataBinding.tvPause.text = "暂停录音"
            }
            VOICE_RECORD_PAUSE -> {
                mDataBinding.rlLoadingAnim.isVisible = false
                mDataBinding.ivPause.setImageResource(R.mipmap.trans_ic_simu_start)
                mDataBinding.tvPause.text = "继续录音"
            }
            else -> {
                updateRecordingBtnText()
                mDataBinding.rlLoadingAnim.isVisible = false
            }
        }
    }

    private fun updateRecordingBtnText(){
        val recognizeLang = mViewModel.getHdToLanguage()
        val btnText = "请说${mParent.langNameFix(recognizeLang?.name ?: "")}，开始同传"
        mDataBinding.tvBtnText.text = btnText
    }

    private fun updateVoicePlayButton(open:Boolean = Preferences.simultaneousVoicePlay){
        if (open && !mViewModel.getHdToLanguage()?.ttsCode.isNullOrEmpty()){
            mParent.setAutoVoicePlay(true)
            mDataBinding.ivVoicePlay.setImageResource(R.drawable.trans_voice_play_gif2)
            mDataBinding.ivVoicePlay.startDrawableAnimation()
        }
        else{
            mParent.setAutoVoicePlay(false)
            mParent.stopPlaying()
            mDataBinding.ivVoicePlay.setImageResource(R.mipmap.ic_voice_close)
        }
    }

    private fun updateListMaskVisible(){
        val layoutManager = mDataBinding.rvWhole.layoutManager as LinearLayoutManager
        val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
        var top = 0
        var childView: View? = null
        if (firstVisibleItemPosition == 0 && topSpaceVm.height == 0){
            if (layoutManager.childCount > 1){
                childView = layoutManager.getChildAt(1)
            }
        }
        else{
            childView = layoutManager.getChildAt(0)
        }

        childView?.let {
            top = it.top
        }

        mDataBinding.vListMask.isVisible = firstVisibleItemPosition > 1 || top != 0
    }

    /**
     * 显示段落
     */
    private val updateSubsectionHolder = AtomicReference<TransSubsection>()
    override fun displaySubsection(data: TransSubsection){
        updateSubsectionHolder.set(data)

        if (mUpdateSubsectionRunnable != null)
            return

        mUpdateSubsectionRunnable = Runnable {
            LogUtil.d("更新显示内容")
            updateSubsectionHolder.get()?.let { mData ->
                val index = mSubsectionVm.indexOf(mData)
                if (index == -1){
                    mSubsectionVm.add(mData)
                }
                else {
                    mSubsectionVm.updateSubsection(mData)
                }

                mDataBinding.rvWhole.post {
                    mSubsectionVm.updateHighlightState()
                }
            }


            mDataBinding.rvWhole.scrollToBottom()
            updateListMaskVisible()

            mParent.getHandler().removeCallbacks(mUpdateSubsectionRunnable!!)
            mUpdateSubsectionRunnable = null
        }

        mParent.getHandler().postDelayed(mUpdateSubsectionRunnable!!,300)
    }

    override fun onStateChange() {
        if (!isInitViews)
            return

        if (mParent.getSubsectionSet().isContentNotEmpty()){
            mDataBinding.rlDefaultBg.isVisible = false
        }

        onRecordingStateChange(mViewModel.voiceState.value!!)
        onChronometerTickListener(mParent.recordingDuration)

        onRotateChanged(mParent.isRotate)

        mSubsectionVm.updateList(mParent.getSubsectionSet().getList())

        updateVoicePlayButton()

        if (mParent.isAndroid10Higher() && !mParent.audioSourceSettings.isRecordSys) {
            showHideHeadsetTips(mParent.mAudioManager.isWiredHeadsetOn())
        }
    }

    override fun onRotateChanged(isRotate: Boolean) {
        val rotationValue = if (isRotate) 180f else 0f
        mDataBinding.topLayout.rotationX = rotationValue
        mDataBinding.topLayout.rotationY = rotationValue
        topSpaceVm.height = if (isRotate) mParent.resources.getDimensionPixelSize(R.dimen.dp_60dp) else 0
    }

    override fun onChronometerTickListener(timeMillis: Long) {

        val durationStr =  SimpleDateFormat("mm:ss", Locale.getDefault()).format(Date(timeMillis))
        mDataBinding.tvTimer.text = durationStr
    }

    override fun onContentChange(taskId: String) {

        val data = mParent.getSubsectionSet().getItemByTaskId(taskId)
        data?.let {
            displaySubsection(it)
        }
    }

    override fun onDevicesConnect(isConnect: Boolean) {
        showHideHeadsetTips(isConnect)
    }

    override fun onViewClick(v: View?) {
        mDataBinding.apply {
            when (v) {
                btnStart -> {
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "全屏",
                        if (mViewModel.isRecording()) "结束录音按钮" else "开始录音按钮"
                    )
                    mParent.startAndStop(true)
                }
                btnPause -> {
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "全屏",
                        if (mViewModel.isRecording()) "暂停录音按钮" else "继续录音按钮"
                    )
                    mParent.startAndPause(true)
                }
                btnStop -> {
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "全屏",
                        "结束录音按钮"
                    )
                    mParent.stopRecording()
                }
                btnCopy -> {
                    if (ivCopyIcon.alpha != 1f){
                        return
                    }

                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "全屏",
                        "复制按钮"
                    )

                    val text = mSubsectionVm.getAllContent()
                    if (text.isNotEmpty()) {
                        val isWrite = ClipboardUtils.writeClipText(text)
                        if (isWrite){
                            ToastUtils.showNormal(resources.getString(R.string.copy_success_tips))
                        }
                    }
                }
                btnSysSound -> {
                    showHideHeadsetTips(false)
                    mParent.showRecordingSettingDialog()
                }
                btnCloseHeadsetTips -> {
                    showHideHeadsetTips(false)
                }
                btnFloatWindow -> {
                    mParent.showFloatWindow()
                }

                btnVoicePlay -> {
                    val isOpen = !mDataBinding.ivVoicePlay.isPlaying
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "全屏",
                        "${if (isOpen) "开启" else "关闭"}译文播报"
                    )
                    Preferences.simultaneousVoicePlay = isOpen
                    updateVoicePlayButton(isOpen)
                }
            }
        }
    }

}